package com.ebai.product.management.service.system;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.ebai.product.management.base.cache.service.MessageCacheImpl;
import com.ebai.product.management.base.utils.SysCode;
import com.ebai.product.management.framework.utils.TreeUtils;
import com.ebai.product.management.model.entity.Auth;
import com.ebai.product.management.model.entity.Role;
import com.ebai.product.management.model.entity.RoleAuth;
import com.ebai.product.management.model.vojo.AuthTreeVo;
import com.ebai.product.management.model.vojo.RoleCheckVo;
import com.ebai.product.management.repository.system.AuthRepository;
import com.ebai.product.management.repository.system.RoleAuthRepository;
import com.ebai.product.management.repository.system.RoleRepository;

import net.sf.json.JSONArray;

@Service
public class RoleService {

    @Autowired
    private RoleRepository roleRepository;
    
    @Autowired
    private AuthRepository authRepository;
    
    @Autowired
    private RoleAuthRepository roleAuthRepository;

    /**
     * 依据条件查询分页数据
     * @param page
     * @param size
     * @param roleQuery
     * @return
     */
    public Page<Role> queryPage(Integer page, Integer size, final Role roleQuery) {
        Pageable pageable = PageRequest.of(page-1, size, Sort.Direction.ASC, "pid");
        Page<Role> rolePage = this.roleRepository.findAll(new Specification<Role>(){
            public Predicate toPredicate(Root<Role> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                // 过滤已经删除条件
                list.add(criteriaBuilder.notEqual(root.get("isDelete").as(String.class), SysCode.DICT_TYSF.YES));

                // 过滤角色名称条件
                if ( StringUtils.isNotBlank(roleQuery.getRoleName()) ){
                    list.add(criteriaBuilder.like(root.get("roleName").as(String.class), "%"+ roleQuery.getRoleName() +"%"));
                }
                // 过滤角色类型条件
                if ( StringUtils.isNotBlank(roleQuery.getRoleType()) ){
                    list.add(criteriaBuilder.equal(root.get("roleType").as(String.class), roleQuery.getRoleType()));
                }
                // 过滤角色描述条件
                if ( StringUtils.isNotBlank(roleQuery.getRoleDescribe()) ){
                    list.add(criteriaBuilder.like(root.get("roleDescribe").as(String.class), "%"+ roleQuery.getRoleDescribe() +"%"));
                }
                // 过滤创建时间条件
                if ( StringUtils.isNotBlank(roleQuery.getCreateTimeBetween()) ){
                    String[] createTime = roleQuery.getCreateTimeBetween().split(" ~ ");
                    list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(Timestamp.class), Timestamp.valueOf(createTime[0] + " 00:00:00")));
                    list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(Timestamp.class), Timestamp.valueOf(createTime[1] + " 23:59:59")));
                }
                list.add(criteriaBuilder.notEqual(root.get("roleType").as(String.class), SysCode.DEFAULT_USER.SADMIN_ROLE));
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, pageable);

        return rolePage;
    }

    /**
     * 依据条件查询对象是否存在
     * @param roleName
     * @return
     */
    public Map<String, Object> checkExist(String roleName) {
        Map<String, Object> result = new HashMap<String, Object>();

        Role role = this.queryByRoleName(roleName);
        if (null != role) {
            result.put("success", true);
            result.put("msg", MessageCacheImpl.getMsg("Global.Operate.Message.Repeat"));
        }
        else {
            result.put("success", false);
        }

        return result;
    }

    /**
     * 依据条件获取数据对象
     * @param roleName
     * @return
     */
    public Role queryByRoleName(String roleName) {
        return this.roleRepository.findRoleByRoleName(roleName);
    }

    /**
     * 保存或更新表单数据
     * @param entity
     * @return
     */
    public Map<String, Object> saveData(Role entity) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            if (StringUtils.isBlank(entity.getPid())) {
//                entity.setRoleType("CUSTOM");
                entity.setIsTransfer(SysCode.DICT_TYSF.YES);
                entity.setIsDelete(SysCode.DICT_TYSF.NO);
                this.roleRepository.save(entity);
            }
            else {
                Role role = this.roleRepository.findByPid(entity.getPid());
                role.setRoleName(entity.getRoleName());
                role.setRoleDescribe(entity.getRoleDescribe());
                role.setRoleType(entity.getRoleType());
                if (StringUtils.isNotBlank(entity.getRoleType())) {
                    role.setRoleType(entity.getRoleType());
                }
                if (StringUtils.isNotBlank(entity.getIsTransfer())) {
                    role.setIsTransfer(entity.getIsTransfer());
                }
                if (StringUtils.isNotBlank(entity.getIsDelete())) {
                    role.setIsDelete(entity.getIsDelete());
                }
                role.setLastUpdateTime(null);
                this.roleRepository.save(role);
            }

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Failure") + e.getMessage());
        }

        return result;
    }

    /**
     * 依据主键执行逻辑删除
     * @param ids
     * @return
     */
    public Map<String, Object> dropData(String ids) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            if (StringUtils.isNotBlank(ids)) {
                for (String pid : ids.split(",")) {
                    Role entity = this.roleRepository.findByPid(pid);
                    entity.setIsDelete(SysCode.DICT_TYSF.YES);
                    this.roleRepository.save(entity);
                }
            }

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("Global.DeleteData.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("Global.DeleteData.Message.Failure") + e.getMessage());
        }

        return result;
    }
    
    /**
     * 获取人员授权角色复选框数据
     * @param userPid
     * @return
     */
    public String getRoleCheckData(String userPid) {
    	List<Object> perms = roleRepository.selectRoleByUserId(userPid);
    	List<RoleCheckVo> chkRoleData = new ArrayList<RoleCheckVo>();
    	RoleCheckVo roleCheckVo = null;
    	if (null != perms && perms.size()>0) {
    		for (Object perm : perms) {
                if (null != perms) {
        			roleCheckVo = new RoleCheckVo();
                	Object[] rowArray = (Object[]) perm;
                	roleCheckVo.setId((String) rowArray[0]);
                	roleCheckVo.setName((String) rowArray[2]);
                	roleCheckVo.setType((String) rowArray[3]);
                	if (StringUtils.isNotEmpty((String) rowArray[4])) {
                		roleCheckVo.setOn(true);
                	}
                	
                	chkRoleData.add(roleCheckVo);
                }
            }
    	}
    	JSONArray jsonArray = JSONArray.fromObject(chkRoleData);
    	System.out.println(jsonArray.toString());
    	
    	return jsonArray.toString();
    }
    
    /**
     * 根据用户ID查询角色权限
     * @param userId
     * @return
     */
    public Set<String> selectRoleKeys(String userPid) {
        List<Object> perms = roleRepository.selectRolesByUserId(userPid);
        Set<String> permsSet = new HashSet<>();
        for (Object perm : perms) {
            if (null != perms) {
            	Object[] rowArray = (Object[]) perm;
                permsSet.addAll(Arrays.asList(((String) rowArray[2]).trim().split(",")));
            }
        }
        return permsSet;
    }
    
    /**
     * 返回所以角色集合
     * @return
     */
    public Set<String> selectRolesAll() {
    	List<Role> roles = this.roleRepository.findRolesAll();
    	Set<String> permsSet = new HashSet<>();
    	for (Role role : roles) {
    		permsSet.add(role.getRoleType());
		}
    	
    	return permsSet;
    }
    
    /**
     * 返回权限树集合数据
     * @return
     */
    public List<AuthTreeVo> selectAuthTreeData(){
    	List<Auth> auths = this.authRepository.findAuthsAll();
    	List<AuthTreeVo> treeAuths = TreeUtils.getTreePerms(auths, "-1");
    	JSONArray jsonArray = JSONArray.fromObject(treeAuths);
    	System.out.println(jsonArray.toString());
    	
    	return treeAuths;
    }
    
    /**
     * 获取角色所拥有的权限集合
     * @param rolePid
     * @return
     */
    public List<String> getRoleAuthPids(String rolePid) {
    	List<Object> objRoleAuths = roleAuthRepository.selectAuthsByRoleid(rolePid);
    	List<String> listRoleAuth = new ArrayList<String>();
    	if (null != objRoleAuths) {
    		for (Object obj : objRoleAuths) {
            	listRoleAuth.add((String) obj);
            }
        }
    	
    	JSONArray jsonArray = JSONArray.fromObject(listRoleAuth);
    	System.out.println(jsonArray.toString());
    	
    	return listRoleAuth;
    }
    
    /**
     * 保存角色权限数据
     * @param roleid
     * @param authids
     * @return
     */
    public Map<String, Object> saveRolePermsData(String rolePid, String authids) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
        	String[] authidArr = authids.split(",");
        	RoleAuth roleAuth = null;
        	List<RoleAuth> roleAuthList = new ArrayList<RoleAuth>();
        	for (int i = 0; i < authidArr.length; i++) {
        		if (StringUtils.equals(authidArr[i], "0")) {
        			continue;
        		}
        		roleAuth = new RoleAuth();
        		roleAuth.setRolePid(rolePid);
        		roleAuth.setAuthPid(authidArr[i]);
        		
        		roleAuthList.add(roleAuth);
			}
        	// 先删除
        	roleAuthRepository.deleteRoleAuthByRoleid(rolePid);
        	// 后插入
        	roleAuthRepository.saveAll(roleAuthList);
        	
            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Failure") + e.getMessage());
        }

        return result;
    }
}
